import {Trigger} from "solar/w3ts/handles/trigger";
import BaseUtil from "solar/util/BaseUtil";
import {Unit} from "solar/w3ts/handles/unit";
import RandomUtil from "solar/util/RandomUtil";
import {OrderId} from "solar/w3ts/globals/order";
import SelectUtil from "solar/util/SelectUtil";
import ForceUtil from "../../solar/util/ForceUtil";


/**
 * creeper可以理解为怪物或敌人
 * 刷攻击怪物
 */
export default class CreeperAttackWaveState {
    /**
     * config
     * 选择难度后可根据难度修改此处配置的值
     */
    static config: {
        start_time: number,//刷兵开始时间
        creeper_palyer_no: number,//怪物的所属玩家号 1=玩家1 12=玩家12
        wave_interval: number,//每波间隔
        wave_creeper_interval: number,//每波刷兵间隔
        wave_creeper_count: number,//每波刷兵数量
        wave_level_max: number,//刷兵最大波数
        regions: string[],//刷怪区域
        is_sharing_mode: boolean,//是否共享模式 true = 所有玩家共享怪物（比如生存图 防守图） false = 每个玩家单独刷这么多怪物 （比如塔防图）
        unit_ids: string[],//普通怪物 必须配置
        elite_unit_ids: string[],//精英怪物 缺省值会取unit_ids
        elite_wave: number,//0=没有精英怪 1=每波都有 5=每5波有
        elite_count: number,//精英怪数量
        boss_unit_ids: string[],//boss怪物 缺省值会取unit_ids
        boss_wave: number,//0=没有boss怪 1=每波都有 5=每5波有

    } = {
        start_time: 3,
        creeper_palyer_no: 12,
        wave_interval: 3,
        wave_creeper_interval: 0.5,
        wave_creeper_count: 3,
        wave_level_max: 30,
        regions: [],
        is_sharing_mode: false,
        unit_ids: [],
        elite_unit_ids: [],
        elite_wave: 0,
        elite_count: 0,
        boss_unit_ids: [],
        boss_wave: 5,
    }
    //var
    static level: number = 0;
    //下一波的计时器 窗口
    static nextWaveTimerdialog: timerdialog = null;

    constructor() {
        CreateFogModifierRectBJ(true, Player(CreeperAttackWaveState.config.creeper_palyer_no - 1), FOG_OF_WAR_VISIBLE, GetPlayableMapRect());
        BaseUtil.runLater(CreeperAttackWaveState.config.start_time, CreeperAttackWaveState.onWave);
    }


    static onWave(this: void) {
        if (CreeperAttackWaveState.nextWaveTimerdialog) {
            DestroyTimerDialog(CreeperAttackWaveState.nextWaveTimerdialog)
        }
        CreeperAttackWaveState.level++;
        let config = CreeperAttackWaveState.config;
        //one case  刷普通怪
        let wave_creeper_count = 0;
        let unitIdStr = config.unit_ids[(CreeperAttackWaveState.level - 1) % config.unit_ids.length]
        let unitId = FourCC(unitIdStr)
        BaseUtil.runLater(config.wave_creeper_interval, () => {
            if (wave_creeper_count >= config.wave_creeper_count) {
                return;
            }
            //one case  boss
            if (config.boss_wave > 0 && CreeperAttackWaveState.level % config.boss_wave == 0) {
                let bossIndex = CreeperAttackWaveState.level / config.boss_wave;
                bossIndex = math.floor(bossIndex)
                unitIdStr = config.boss_unit_ids[(bossIndex - 1) % config.boss_unit_ids.length]
                if (unitIdStr) {
                    unitId = FourCC(unitIdStr)
                }
                wave_creeper_count = config.wave_creeper_count//只刷一个boss
            } else if (config.elite_wave > 0 && CreeperAttackWaveState.level % config.elite_wave == 0) {
                //one case  最后几个 刷精英怪
                if (wave_creeper_count >= config.wave_creeper_count - config.elite_count) {
                    unitIdStr = config.elite_unit_ids[(CreeperAttackWaveState.level - 1) % config.elite_unit_ids.length]
                    if (unitIdStr) {
                        unitId = FourCC(unitIdStr)
                    }
                }
            }
            //开始刷怪
            if (config.is_sharing_mode) {
                //开始刷兵（按所有玩家共享怪物刷）
                let regionValName: string = config.regions[RandomUtil.nextInt(0, config.regions.length - 1)];
                let region: rect = globals[regionValName];
                CreeperAttackWaveState.createCreeper(unitId, region)
            } else {        //开始刷兵（为每个还在游戏中的玩家刷）
                for (let i = 0; i < config.regions.length; i++) {
                    let player = ConvertedPlayer(i + 1)
                    if (GetPlayerSlotState(player) == PLAYER_SLOT_STATE_PLAYING &&
                        GetPlayerController(player) == MAP_CONTROL_USER) {
                        let regionValName: string = config.regions[i];
                        let region: rect = globals[regionValName];
                        CreeperAttackWaveState.createCreeper(unitId, region)
                    }
                }
            }
            wave_creeper_count++;
            if (wave_creeper_count >= config.wave_creeper_count) {
                //one case
                if (CreeperAttackWaveState.level >= config.wave_level_max) {
                    DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, '游戏将在60秒后胜利！');
                    DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, '游戏将在60秒后胜利！');
                    DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, '游戏将在60秒后胜利！');
                    BaseUtil.runLater(50, () => {
                        ForceUtil.forUserForce(player => {
                            let number = DzAPI_Map_GetStoredInteger(player, "zui_gao");
                            number = Math.max(number, gameDifficulty)
                            DzAPI_Map_StoreInteger(player, "zui_gao", number);
                            let giveStar = GetRandomInt(1, 2)
                            DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, '你获得了难度' + gameDifficulty + "积分:" + giveStar);
                            DzAPI_Map_StoreInteger(player, "nandu_" + gameDifficulty, giveStar);
                            if (gameDifficulty == 2) {
                                DzAPI_Map_StoreInteger(player, "ui_item_1", 1);
                            }
                            if (gameDifficulty == 3) {
                                DzAPI_Map_StoreInteger(player, "ui_item_2", 1);
                            }
                            if (gameDifficulty == 4) {
                                DzAPI_Map_StoreInteger(player, "ui_item_3", 1);
                            }

                            DzAPI_Map_Stat_SetStat(Player(0), "home1", DzAPI_Map_GetStoredInteger(player, "nandu_1") + "")
                            DzAPI_Map_Stat_SetStat(Player(0), "home2", number + "")

                        })
                    })
                    BaseUtil.runLater(60, () => {
                        ForceUtil.forUserForce(player => {
                            CustomVictoryBJ(player, true, true);
                        })
                    })
                    return
                }
                BaseUtil.runLater(CreeperAttackWaveState.config.wave_interval, CreeperAttackWaveState.onWave)
                //下一波的计时器窗口提示
                let timer = CreateTimer();
                CreeperAttackWaveState.nextWaveTimerdialog = CreateTimerDialogBJ(timer, "下一波");
                TimerStart(timer, CreeperAttackWaveState.config.wave_interval, false, null);
            }
        }, config.wave_creeper_count)


    }

    static createCreeper(unitId: number, region: rect) {
        let creeper_palyerIndex = CreeperAttackWaveState.config.creeper_palyer_no - 1;
        let x = GetRandomReal(GetRectMinX(region), GetRectMaxX(region));
        let y = GetRandomReal(GetRectMinY(region), GetRectMaxY(region));
        let unit = new Unit(creeper_palyerIndex, unitId, x, y, 0)
        if (gameDifficulty && gameDifficulty > 1) {
            let multiple = (gameDifficulty - 1) * gameDifficulty;
            // new hp
            let new_hp = (GetUnitState(unit.handle, UNIT_STATE_MAX_LIFE) * multiple);
            new_hp = (GetUnitState(unit.handle, UNIT_STATE_MAX_LIFE) + new_hp);
            SetUnitState(bj_lastCreatedUnit, UNIT_STATE_MAX_LIFE, new_hp);
            SetUnitLifePercentBJ(bj_lastCreatedUnit, 100);
            //  new_dmg
            let new_dmg = (GetUnitState(unit.handle, ConvertUnitState(0x12)) * gameDifficulty);
            new_dmg = (GetUnitState(unit.handle, ConvertUnitState(0x12)) + new_dmg);
            SetUnitState(bj_lastCreatedUnit, ConvertUnitState(0x12), new_dmg);
            // new hj
            let new_hj = (GetUnitState(unit.handle, ConvertUnitState(0x20)) * gameDifficulty);
            new_hj = (GetUnitState(unit.handle, ConvertUnitState(0x20)) + new_hj);
            SetUnitState(bj_lastCreatedUnit, ConvertUnitState(0x20), new_hj);

        }
        let enemy = SelectUtil.getAnEnemy(creeper_palyerIndex)
        if (enemy == null) {
            return
        }
        unit.issueOrderAt(OrderId.Attack, GetUnitX(enemy), GetUnitY(enemy))
    }

}
